package com.pickgliss.loader
{
	import com.pickgliss.events.UIModuleEvent;
	import com.pickgliss.ui.ComponentFactory;
	import com.pickgliss.ui.ComponentSetting;
	
	import deng.fzip.FZip;
	import deng.fzip.FZipFile;
	
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.external.ExternalInterface;
	import flash.net.URLVariables;
	import flash.utils.ByteArray;

	[Event(name="uiModuleComplete",type="com.pickgliss.events.UIModuleEvent")]
	[Event(name="uiModuleError",type="com.pickgliss.events.UIModuleEvent")]
	[Event(name="uiMoudleProgress",type="com.pickgliss.events.UIModuleEvent")]
	public class UIModuleLoader extends EventDispatcher
	{
		public static const CONFIG_ZIP:String = "configZip";
		public static const CONFIG_XML:String = "configXml";
		private static var _instance:UIModuleLoader;
		private var _uiModuleLoadMode:String = CONFIG_XML;
		public static function get Instance():UIModuleLoader
		{
			if(_instance == null)
			{
				_instance = new UIModuleLoader();
			}
			return _instance;
		}

		public function UIModuleLoader()
		{
			_queue = new Vector.<String>();
			_loadingLoaders = new Vector.<BaseLoader>();
		}

		private var _loadingLoaders:Vector.<BaseLoader>

		private var _queue:Vector.<String>;
		
		public function addUIModlue(module:String):void
		{
			if(_queue.indexOf(module) != -1)return;
			_queue.push(module);
			if(!isLoading && _zipLoadComplete)loadNextModule();
		}
		
		public function addUIModuleImp(module:String,state:String = null):void
		{
			var index:int = _queue.indexOf(module);
			if(index != -1)
			{
				_queue.splice(index,1);
			}
			if(_zipLoadComplete)
			{
				loadModuleConfig(module,state);
			}
			else
			{
				_queue.unshift(module);
			}
		}
		
		private var _zipPath:String = "";
		private var _zipLoadComplete:Boolean = true;
		public function setup():void
		{
			_zipPath = ComponentSetting.getUIConfigZIPPath();
			_uiModuleLoadMode = CONFIG_ZIP;
			_zipLoadComplete = false;
			loadZipConfig();
		}
		
		private function loadZipConfig():void
		{
			if(_uiModuleLoadMode == CONFIG_XML)return;
			var md5:String = ComponentSetting.getUrlMd5(_zipPath);
			var ba:ByteArray = LoaderSavingManager.loadCachedFile(_zipPath,false,md5);
			if(ba && ba.length > 0)
			{
				if(ComponentSetting.checkNeedAnalyzeMd5(md5))
				{
					if(ComponentSetting.compareMD5(ba,md5))
					{
						trace("文件解码md5成功5： ： ：" + _zipPath);
						//比对成功
						var temp:ByteArray = new ByteArray();
						ba.position = 37;
						ba.readBytes(temp);
						unZipFile(temp);
					}
					else
					{
						LoaderSavingManager.clearFiles(_zipPath);
						loadZipFromWeb();
					}
				}
				else
				{
					unZipFile(ba);
				}
			}
			else
			{
				loadZipFromWeb();
			}
		}
		
		private function loadZipFromWeb():void
		{
			var arg:URLVariables = new URLVariables();
			var md5:String = ComponentSetting.getUrlMd5(_zipPath);
			arg['lv'] = md5;
			if(_isSecondLoad)
			{
				arg['rnd'] = Math.random();
			}
			var loader:BaseLoader = new BaseLoader(LoaderManager.Instance.getNextLoaderID(),_zipPath,arg);
			loader.addEventListener(LoaderEvent.COMPLETE,__onLoadZipComplete);
			loader.loadFromWeb();
		}

		private var _isSecondLoad:Boolean = false;
		private function __onLoadZipComplete(event:LoaderEvent):void
		{
			event.currentTarget.removeEventListener(LoaderEvent.COMPLETE,__onLoadZipComplete);
			var md5:String = ComponentSetting.getUrlMd5(_zipPath);
			if(ComponentSetting.checkNeedAnalyzeMd5(md5))
			{
				if(ComponentSetting.compareMD5(event.loader.content,md5))
				{
					trace("文件解码md5成功5： ： ：" + _zipPath);
					//比对成功
					var temp:ByteArray = new ByteArray();
					event.loader.content.position = 37;
					event.loader.content.readBytes(temp);
					LoaderSavingManager.cacheFile(_zipPath,event.loader.content,false,md5);
					unZipFile(temp);
				}
				else
				{
					if(_isSecondLoad)
					{
						
					}
					else
					{
						_isSecondLoad = true;
						loadZipFromWeb();
					}
				}
			}
			else
			{
				unZipFile(event.loader.content);
			}
		}
		
		private function unZipFile(content:ByteArray):void
		{
			var zip:FZip = new FZip();
			zip.addEventListener(Event.COMPLETE,__onZipParaComplete);
			zip.loadBytes(content);
		}

		private function __onZipParaComplete(event:Event):void
		{
			var zip:FZip = event.currentTarget as FZip;
			var count:int = zip.getFileCount();
			for(var i:int = 0;i<count;i++)
			{
				var file:FZipFile = zip.getFileAt(i);
				var xml:XML = new XML(file.content.toString());
				ComponentFactory.Instance.setup(xml);
			}
			_zipLoadComplete = true;
			loadNextModule();
		}
		
		public function get isLoading():Boolean
		{
			return _loadingLoaders.length>0;
		}
		
		private function __onConfigLoadComplete(event:LoaderEvent):void
		{
			event.loader.removeEventListener(LoaderEvent.COMPLETE,__onConfigLoadComplete);
			event.loader.removeEventListener(LoaderEvent.LOAD_ERROR,__onLoadError);
			var index : int = _loadingLoaders.indexOf(event.loader);
			
			if(index != -1)_loadingLoaders.splice(index,1);
			if(event.loader.isSuccess)
			{
				var config:XML = new XML(event.loader.content);
				var resourcePath:String = config.@source;
				resourcePath = ComponentSetting.RESOURCE_PATH + resourcePath;
				ComponentFactory.Instance.setup(config);
				loadModuleUI(resourcePath,event.loader.loadProgressMessage,event.loader.loadCompleteMessage);
			}else
			{
				removeLastLoader(event.loader);
				dispatchEvent(new UIModuleEvent(UIModuleEvent.UI_MODULE_COMPLETE,event.loader));
				loadNextModule();
			}
		}
		
		private function __onLoadError(event:LoaderEvent):void
		{
			dispatchEvent(new UIModuleEvent(UIModuleEvent.UI_MODULE_ERROR,event.loader));
		}
		
		private function __onResourceComplete(event:LoaderEvent):void
		{
			event.loader.removeEventListener(LoaderEvent.LOAD_ERROR,__onLoadError);
			event.loader.removeEventListener(LoaderEvent.PROGRESS,__onResourceProgress);
			event.loader.removeEventListener(LoaderEvent.COMPLETE,__onResourceComplete);
			dispatchEvent(new UIModuleEvent(UIModuleEvent.UI_MODULE_COMPLETE,event.loader));
			removeLastLoader(event.loader);
			loadNextModule();
		}
		
		
		private function removeLastLoader(loader:BaseLoader):void
		{
			var index : int = _loadingLoaders.indexOf(loader);
			if(index != -1)_loadingLoaders.splice(index,1);
			index = _queue.indexOf(loader.loadProgressMessage);
			if(index != -1)_queue.splice(index,1);
			if(loader)loader.dispose();
		}
		
		private function __onResourceProgress(event:LoaderEvent):void
		{
			dispatchEvent(new UIModuleEvent(UIModuleEvent.UI_MODULE_PROGRESS,event.loader));
		}
		
		private function loadNextModule():void
		{
			if(_queue.length <= 0)return;
			var loadingModule:String = _queue[0];
			loadModuleConfig(loadingModule);
		}
		
		private function loadModuleConfig(module:String,state:String=""):void
		{
			if(_uiModuleLoadMode == CONFIG_XML)
			{
				var textLoader:BaseLoader = LoaderManager.Instance.creatLoader(ComponentSetting.getUIConfigXMLPath(module),BaseLoader.TEXT_LOADER);
				textLoader.loadProgressMessage = module;
				textLoader.loadCompleteMessage = state;
				textLoader.addEventListener(LoaderEvent.COMPLETE,__onConfigLoadComplete);
				textLoader.addEventListener(LoaderEvent.LOAD_ERROR,__onLoadError);
				textLoader.loadErrorMessage = "加载UI配置文件"+textLoader.url+"出现错误";
				_loadingLoaders.push(textLoader);
				LoaderManager.Instance.startLoad(textLoader,true);
			}else
			{
				loadModuleUI(ComponentSetting.getUISourcePath(module),module,state);
			}
		}
		
		private function loadModuleUI(uipath:String,module:String = "",state:String = ""):void
		{
			var uiResourceLoader:BaseLoader = LoaderManager.Instance.creatLoader(uipath,BaseLoader.MODULE_LOADER);
			uiResourceLoader.loadProgressMessage = module;
			uiResourceLoader.loadCompleteMessage = state;
			uiResourceLoader.loadErrorMessage = "加载ui资源："+uiResourceLoader.url+"出现错误";
			uiResourceLoader.addEventListener(LoaderEvent.LOAD_ERROR,__onLoadError);
			uiResourceLoader.addEventListener(LoaderEvent.PROGRESS,__onResourceProgress);
			uiResourceLoader.addEventListener(LoaderEvent.COMPLETE,__onResourceComplete);
			_loadingLoaders.push(uiResourceLoader);
			LoaderManager.Instance.startLoad(uiResourceLoader,true);
		}
	}
}